package com.hisense.hiioc.hismartplate.controller;

import com.alibaba.fastjson.JSONObject;
import com.hisense.hiioc.hismartplate.constants.URLConstant;
import com.hisense.hiioc.hismartplate.entity.server.AppVersionEntity;
import com.hisense.hiioc.hismartplate.entity.server.CheckVersionEntity;
import com.hisense.hiioc.hismartplate.server.CmdDispatcher;
import com.hisense.hiioc.hismartplate.service.CoreManagerService;
import com.hisense.hiioc.hismartplate.utils.EmptyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author: almo
 * @Date: 2018/12/26 下午3:04
 * @Version 1.0
 */
@Controller
@RequestMapping(URLConstant.DeviceApkMapping.BASE_URL)
public class ApkController implements CmdDispatcher.ICmdDispatcherListener {
    private static final Logger logger = LoggerFactory.getLogger(ApkController.class);

    @Autowired
    private CoreManagerService coreManagerService;

    @Autowired
    private TaskExecutor taskExecutor;

    @Value("${apkFilePath:/usr/local/downloads/}")
    private String apkFilePath;

    private CmdDispatcher cmdDispatcher = CmdDispatcher.getInstance();

    private CopyOnWriteArrayList<CheckVersionEntity> versionList = new CopyOnWriteArrayList<>();

    public ApkController() {
        cmdDispatcher.initialize(this);
    }

    @RequestMapping("/homePage")
    public String getApkPage(HttpServletRequest request) {
        System.out.println("getApkPage");
        return "apkPage";
    }

    @RequestMapping("/resPage")
    public String getResourcePage() {
        return "resourceUpdatePage";
    }

    @ResponseBody
    @RequestMapping("/update")
    public String updateApk(@RequestParam(value = "all", required = false) boolean isAll,
                            @RequestParam("deviceID") String deviceID,
                            @RequestParam(value = "screenID", required = false) String screenId,
                            @RequestParam(value = "package", required = false) String packageName,
                            @RequestParam(value = "versionCode", required = false) String versionCode,
                            @RequestParam(value = "versionName", required = false) String versionName,
                            @RequestParam(value = "apk") MultipartFile multipartFile,
                            @RequestParam(value = "reboot", required = false) boolean reboot) {

        final String srcFileName = multipartFile.getOriginalFilename();
        final String prexName = srcFileName.substring(srcFileName.lastIndexOf(".")).toLowerCase();
        File targetFile = new File(apkFilePath + "/update" + prexName);
        if (targetFile.exists()) {
            targetFile.delete();
        }

        try {
            multipartFile.transferTo(targetFile);
        } catch (IOException e) {
            e.printStackTrace();
            return "failed";
        }

        AppVersionEntity appVersionEntity = new AppVersionEntity();
        appVersionEntity.setPackageName(packageName);
        appVersionEntity.setUrl(targetFile.getName());
        appVersionEntity.setVersionCode(Integer.valueOf(versionCode));
        appVersionEntity.setVersionName(versionName);
        appVersionEntity.setFileName(srcFileName);
        appVersionEntity.setReboot(reboot);

        if (isAll)
            coreManagerService.updateApkForAll(appVersionEntity);
        else
            coreManagerService.updateApkByScreenId(screenId, appVersionEntity);

        return "success";
    }

    @ResponseBody
    @RequestMapping("/install")
    public String installApk(@RequestParam(value = "all", required = false) boolean isAll,
                             @RequestParam("deviceID") String deviceID,
                             @RequestParam(value = "screenID", required = false) String screenId,
                             @RequestParam(value = "package", required = false) String packageName,
                             @RequestParam(value = "apk") MultipartFile multipartFile,
                             @RequestParam(value = "reboot", required = false) boolean reboot) {

        final String srcFileName = multipartFile.getOriginalFilename();
        final String prexName = srcFileName.substring(srcFileName.lastIndexOf(".")).toLowerCase();
        File targetFile = new File(apkFilePath + "/update" + prexName);
        if (targetFile.exists()) {
            targetFile.delete();
        }

        try {
            multipartFile.transferTo(targetFile);
        } catch (IOException e) {
            e.printStackTrace();
            return "failed";
        }

        AppVersionEntity appVersionEntity = new AppVersionEntity();
        appVersionEntity.setPackageName(packageName);
        appVersionEntity.setUrl(targetFile.getName());
        appVersionEntity.setFileName(srcFileName);
        appVersionEntity.setReboot(reboot);

        if (isAll) {
            coreManagerService.installApkForAll(appVersionEntity);
        } else {
            coreManagerService.installApkByScreenId(screenId, appVersionEntity);
        }
        return "success";
    }

    @ResponseBody
    @RequestMapping("/unInstall")
    public String unInstallApk(@RequestParam(value = "all", required = false) boolean isAll,
                               @RequestParam(value = "deviceID", required = false) String deviceID,
                               @RequestParam(value = "screenID") String screenId,
                               @RequestParam(value = "package") String packageName,
                               @RequestParam(value = "reboot", required = false) boolean reboot) {

        AppVersionEntity appVersionEntity = new AppVersionEntity();
        appVersionEntity.setPackageName(packageName);
        appVersionEntity.setReboot(reboot);
        if (isAll) {
            coreManagerService.unInstallApkForAll(appVersionEntity);
        } else {
            coreManagerService.unInstallApkByScreenId(screenId, appVersionEntity);
        }
        return "success";
    }

    @ResponseBody
    @RequestMapping("/updateRes")
    public String updateResource(
            @RequestParam(value = "all", required = false) boolean isAll,
            @RequestParam(value = "isFile", required = false) boolean isFile,
            @RequestParam("deviceID") String deviceID,
            @RequestParam("screenID") String screenID,
            @RequestParam(value = "package", required = false) String packageName,
            @RequestParam(value = "resource") MultipartFile multipartFile,
            @RequestParam("resPath") String resPath,
            @RequestParam(value = "reboot", required = false) boolean reboot) {

        final String srcFileName = multipartFile.getOriginalFilename();
        final String prexName = srcFileName.substring(srcFileName.lastIndexOf(".")).toLowerCase();

        File targetFile = new File(apkFilePath + srcFileName);
        if (targetFile.exists()) {
            targetFile.delete();
        }

        try {
            multipartFile.transferTo(targetFile);
        } catch (IOException e) {
            e.printStackTrace();
            return "failed";
        }

        if (isAll) {
            coreManagerService.updateResourceForAll(screenID, targetFile.getName(), resPath, packageName, isFile, reboot);
        } else {
            coreManagerService.updateResourceByScreenId(screenID, targetFile.getName(), resPath, packageName, isFile, reboot);
        }


        return "success";
    }

    @RequestMapping("/version")
    public String checkSoftwareVersion(
            Model model,
            @RequestParam(value = "all", required = false) boolean isAll,
            @RequestParam(value = "deviceID", required = false) String deviceID,
            @RequestParam(value = "screenID", required = false) String screenID,
            @RequestParam(value = "packages[]") String[] packages) {

        versionList.clear();
        if (isAll) {
            coreManagerService.softwareVersionCheckForAll(Arrays.asList(packages));
        } else {
            if (EmptyUtils.isEmpty(deviceID) || EmptyUtils.isEmpty(screenID)) {
                return "device id or screen id can not both be null";
            }
            coreManagerService.softwareVersionCheckByScreenId(screenID, Arrays.asList(packages));
        }
        try {
            Thread.sleep(20 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        model.addAttribute("versionList", versionList);
        return "versionMonitor/versionHome";
    }

    @Override
    public void onCheckVersionCmd(String entity) {
        System.out.println("received onCheckVersionCmd: " + entity);
        CheckVersionEntity checkVersionEntity = JSONObject.parseObject(entity,CheckVersionEntity.class);
        versionList.add(checkVersionEntity);
    }
}
